<?php

if (!defined('CORE_PATH'))
    die('Access Denied');

class Page extends Model {

    private $tree = NULL;
    private $rootPage = NULL;
    private $parentPage = NULL;
    private $parentPages = NULL;
    private $childPages = NULL;
    private $relatedPages = NULL;
    protected $tableName = "pages";
    protected $helpers = array('HTML');

    public function __construct($data = NULL, &$tree = NULL) {
        parent::__construct($data);
        $this->setAdjacencyTree($tree);
    }

    /**
     * Sets the adjacencyTree object to use for the traversal
     */
    public function setAdjacencyTree($tree) {
        if (($tree instanceof adjacencyTree) && $tree != NULL) {
            //trigger_error("Invalid Tree Object Passed");
            $this->tree = $tree;
        }
    }

    /**
     * @return adjacencyTree $tree
     */
    public function getAdjacencyTree() {
        return $this->tree;
    }

    public function getId() {
        return $this->getData('id');
    }

    public function getParentId() {
        return $this->getData('ParentID');
    }

    public function getSiteID() {
        return $this->getData('SiteID');
    }

    public function getLeft() {
        return $this->getData('PageLeft');
    }

    public function getRight() {
        return $this->getData('PageRight');
    }

    public function getName() {
        return $this->getData('PageName');
    }

    public function getLinkedName($options = NULL) {
        return $this->HTML->renderLink($this->getName(), $this->getURL(), $options);
    }

    public function getPosition() {
        return $this->getData('PagePosition');
    }

    public function getLevel() {
        return $this->getData('PageLevel');
    }

    public function getAlias() {
        return $this->getData('PageNameAlias');
    }

    public function getDescription() {
        return $this->getData('PageDescription');
    }

    public function getSummary() {
        if (defined("IN_CMS") && IN_CMS) {
            return $this->getData('PageSummary');
        }

        return kan_process_html($this->getData('PageSummary'));
    }

    public function getContentType() {
        return $this->getData('PageContentType');
    }

    public function getPageLayout() {
        return $this->getData('PageLayout');
    }

    public function getContent() {
        global $site, $page;

        if (defined("IN_CMS") && IN_CMS) {
            return $this->getData('PageContent');
        }

        if ($this->getContentType() == "php") {
            $phpContent = $this->getData('PageContent'); // obtain the content
            // buffer the output so we do not truncate current processing
            ob_start();
            eval("?> " . $phpContent); // evaluate the php code by first ending the current one
            $eval_buffer = ob_get_contents(); // obtain the result of the evaluation
            ob_end_clean(); // empty the buffer

            return kan_process_html($eval_buffer); // return the php output for display in template	
        }

        return kan_process_html($this->getData('PageContent'));
    }

    public function getRedirectURL() {
        return $this->getData('RedirectURL');
    }

    public function getURL() {
        $url = "";

        // if a Redirect URL has been specified then use that instead
        if ($this->getRedirectURL() != "") {
            $url = $this->getRedirectURL();

            // if Search Engine Friendly URLs are being used, then check and reformat
        } else if (SEF_URLS) {
            //$url = "../" . SITE_TAG . "/pages" . $this->getPath();
            $url = "../" . SITE_TAG . '/p' . $this->getPath();

            // get the URL is raw format
        } else {
            $url = "../pages/index.php?siteid=" . SITE_TAG . "&page=" . $this->getAlias();
        }

        // lastly, if we are in the CMS, return the url as in
        if (defined("IN_CMS") && IN_CMS) {
            return $url;
        }

        // if we are not in the CMS, then fix the URL so path resolve to the root of the site
        // even if in several sub folders
        return kan_fix_url($url);
    }

    public function hasParentPage() {
        return $this->getParentId() != '';
    }

    public function getRootPage() {
        if ($this->rootPage == NULL) {
            $ppages = $this->getParentPages();
            $this->rootPage = isset($ppages[0]) ? $ppages[0] : $this;
        }

        return $this->rootPage;
    }

    public function getParentPage() {
        if ($this->parentPage == NULL) {
            $data = $this->getAdjacencyTree()->getParentData($this->getId());
            $this->parentPage = new Page($data, $this->getAdjacencyTree());
        }

        return $this->parentPage;
    }

    public function getParentPages($fields = "*") {

        if ($this->parentPages == NULL || is_array($fields)) {
            $parents = $this->getAdjacencyTree()->getParentsData($this->getId());
            $pages = array();

            for ($i = 0; $i < count($parents); $i++) {
                $page = new Page($parents[$i], $this->getAdjacencyTree());

                if ($page->isPublished()) {
                    array_push($pages, $page);
                }
            }

            // cache list for later
            $this->parentPages = $pages;
        }

        return $this->parentPages;
    }

    public function getSubPages($fields = "*", $level = 0) {

        if ($this->childPages == NULL || is_array($fields)) {
            $childNodes = $this->getAdjacencyTree()->getChildNodes($this->getId(), $fields, $level);
            $child_ids = array_keys($childNodes);
            $pages = array();

            for ($i = 0; $i < count($child_ids); $i++) {
                $page = new Page($childNodes[$child_ids[$i]], $this->getAdjacencyTree());

                if ($page->isPublished()) {
                    array_push($pages, $page);
                }
            }

            // cache the pages for later
            $this->childPages = $pages;
        }

        return $this->childPages;
    }

    public function hasSubPages() {
        $db = $this->getDatabase();

        $count = $this->count(array(
            'filter' => array('ParentID' => $this->getId())
        ));

        return $count > 0;
    }

    public function getRelatedPages($fields = "*") {

        if ($this->relatedPages == NULL || is_array($fields)) {
            $siblings = $this->getAdjacencyTree()->getSiblings($this->getId(), $fields);
            $sibling_ids = array_keys($siblings);

            $pages = array();

            for ($i = 0; $i < count($siblings); $i++) {
                $page = new Page($siblings[$sibling_ids[$i]], $this->getAdjacencyTree());

                if ($page->isPublished()) {
                    array_push($pages, $page);
                }
            }

            // cache returned pages for later use and performance improvement
            $this->relatedPages = $pages;
        }

        return $this->relatedPages;
    }

    public function getPath() {
        return $this->getData('PagePath');
    }

    public function getBreadCrumb($separator = "-") {
        $location = "<a href='" . kan_site_home() . "'>Home</a>";

        $parentPages = $this->getParentPages();

        for ($i = 0; $i < count($parentPages); $i++) {
            $page = $parentPages[$i];
            $location .= " $separator <a href='{$page->getURL()}'>{$page->getName()}</a>";
        }

        $location .= " $separator <a href='{$this->getURL()}'>{$this->getName()}</a>";

        return $location;
    }

    public function isCurrentPage() {
        return $_SERVER['PATH_INFO'] == "/" . $_GET['siteid'] . $this->getPath();
    }

    public function isPublished() {
        return $this->getData('Published') == 1;
    }

    public function getBlocks() {
        $db = $this->getDatabase();

        $query = sprintf("SELECT * FROM page_blocks WHERE PageID = %s, ", $this->getId());
        $db->query($query, true);

        $blocks = array();
        for ($i = 0; $i < $db->getResultCount(); $i++) {
            array_push($blocks, new Block($db->getRow($i), $this));
        }

        return $blocks;
    }

    public function toHTMLList($class = 'page-list', $depth = 100, $pages = NULL) {

        if ($pages == NULL) {
            $pages = array();
            $pages[] = &$this;
        }

        if (!is_array($pages)) {
            trigger_error("Supplied Parameter Is Not An Array");
        }

        if (count($pages) == 0) {
            return;
        }

        echo "<ul class='$class'>";

        $this->printList($pages, $depth);

        echo "</ul>";
    }

    public function listSubPages($class = 'page-list', $depth = 3) {
        $this->toHTMLList($class, $depth, $this->getSubPages());
    }

    private function printList($pages, $depth, $startDepth = 1) {
        $currentDepth = $startDepth;
        $thisDepth = $startDepth;

        foreach ($pages as $page) {

            if (!$page->isPublished()) {
                continue;
            }

            $id = $page->getId();
            $name = $page->getName();
            $url = $page->getURL();
            $current = stristr($_SERVER['REQUEST_URI'], $page->getURL()) ? 'class="current"' : "";

            echo "<li><a id='$id' data-id='$id' href='$url' $current >$name</a>";

            $subPages = $page->getSubPages(array('id', 'SiteID', 'PageName', 'PagePath', 'PageNameAlias', 'RedirectURL', 'Published'));

            if ($page instanceof Page && count($subPages) > 0 && $currentDepth < $depth) {

                echo "<ul>";
                $this->printList($subPages, $depth, ++$currentDepth);
                echo "</ul>";
            }

            echo "</li>";

            $currentDepth = $thisDepth;
        }
    }

    public function toJSON() {
        $this->setData('URL', $this->getURL());

        return parent::toJSON();
    }

}

?>
